package com.cyf.third.kuting.service.impl;

import com.cyf.activemq.network.bean.*;
import com.cyf.activemq.network.bean.third.kuting.MqKTCreOrderNoticeReq;
import com.cyf.activemq.network.bean.third.kuting.MqKTCreOrderNoticeRsp;
import com.cyf.activemq.network.bean.third.kuting.MqKTDelOrderNoticeReq;
import com.cyf.activemq.network.bean.third.kuting.MqKTDelOrderNoticeRsp;
import com.cyf.activemq.service.SendMsgService;
import com.cyf.db.bean.Parking;
import com.cyf.db.bean.ThirdFee;
import com.cyf.db.mapper.ParkingMapper;
import com.cyf.db.mapper.ThirdFeeMapper;
import com.cyf.db.mapper.ThirdParkingMapMapper;
import com.cyf.redis.RedisService;
import com.cyf.third.ThirdConfig;
import com.cyf.third.kuting.network.bean.*;
import com.cyf.third.kuting.service.KTService;
import com.cyf.util.BasicProperties;
import com.cyf.util.DateUtil;
import com.cyf.util.ObjectMapperUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 第三方-酷停
 * Created by cage on 2017/2/6.
 */
@Service
public class KTServiceImpl implements KTService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private ParkingMapper parkingMapper;
    @Autowired
    private ThirdFeeMapper thirdFeeMapper;
    @Autowired
    private ThirdParkingMapMapper thirdParkingMapMapper;
    @Autowired
    private SendMsgService sendMsgService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private BasicProperties basicProperties;

    @Override
    public CreOrderNoticeRsp creOrderNotice(CreOrderNoticeReq req) {
        CreOrderNoticeRsp rsp = new CreOrderNoticeRsp();
        rsp.setResult(0);
        try {
            // 1、校验参数信息
            if (req.getPlateNum().length() < 7) {
                rsp.setMsg("参数车牌号错误！");
                return rsp;
            }
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            format.parse(req.getStartTime());
            format.parse(req.getEndTime());
            // 校验parkingId
            List<Integer> parkingIds = thirdParkingMapMapper.getByThirdId(ThirdConfig.KUTING);
            if (parkingIds != null && !parkingIds.contains(req.getParkingId())) {
                rsp.setMsg("参数车场id错误！");
                return rsp;
            }
            // 2、通知车场
            String uuid = UUID.randomUUID().toString();
            MqKTCreOrderNoticeReq mqKTCreOrderNoticeReq = new MqKTCreOrderNoticeReq();
            mqKTCreOrderNoticeReq.setOptid(MqBusinessOpt.KT_CREORDERNOTICE);
            mqKTCreOrderNoticeReq.setUuid(uuid);
            mqKTCreOrderNoticeReq.setParkingId(req.getParkingId());
            mqKTCreOrderNoticeReq.setPlate(req.getPlateNum());
            mqKTCreOrderNoticeReq.setStartTime(req.getStartTime());
            mqKTCreOrderNoticeReq.setEndTime(req.getEndTime());
            sendMsgService.sendQueueMessageText(ObjectMapperUtils.getObjectMapper().writeValueAsString(mqKTCreOrderNoticeReq));
            Object result = redisService.getWithExpireTime(uuid, basicProperties.getAppNetworkTimeOut());
            if (result == null) {
                rsp.setMsg("网络异常！");
                logger.error("消息队列中获取消息失败, 车位预定信息通知车场失败！");
                return rsp;
            }
            MqKTCreOrderNoticeRsp mqKTCreOrderNoticeRsp = (MqKTCreOrderNoticeRsp) result;
            if (mqKTCreOrderNoticeRsp.getResult() == MqBusinessRsp.ERROR) {
                rsp.setMsg("车位预定信息通知车场失败！");
                logger.error("车位预定信息通知车场失败，车场返回错误信息：{}", mqKTCreOrderNoticeRsp.getStrError());
                return rsp;
            }
            rsp.setResult(1);
        } catch (ParseException e) {
            logger.error("酷停平台发送车位预定信息，保存异常：日期格式化错误：{}", e);
            rsp.setMsg("日期格式错误！");
        } catch (Exception e) {
            logger.error("云端将酷停的车位预定的信息通知车场异常：{}", e);
            rsp.setMsg("服务器异常！");
        }
        return rsp;
    }

    @Override
    public DelOrderNoticeRsp delOrderNotice(DelOrderNoticeReq req) {
        DelOrderNoticeRsp rsp = new DelOrderNoticeRsp();
        rsp.setResult(0);
        try {
            // 1、校验参数信息
            if (req.getPlateNum().length() < 7) {
                rsp.setMsg("参数车牌号错误！");
                return rsp;
            }
            // 校验parkingId
            List<Integer> parkingIds = thirdParkingMapMapper.getByThirdId(ThirdConfig.KUTING);
            if (parkingIds != null && !parkingIds.contains(req.getParkingId())) {
                rsp.setMsg("参数车场id错误！");
                return rsp;
            }
            // 2、通知车场
            String uuid = UUID.randomUUID().toString();
            MqKTDelOrderNoticeReq mqKTDelOrderNoticeReq = new MqKTDelOrderNoticeReq();
            mqKTDelOrderNoticeReq.setOptid(MqBusinessOpt.KT_DELORDERNOTICE);
            mqKTDelOrderNoticeReq.setUuid(uuid);
            mqKTDelOrderNoticeReq.setParkingId(req.getParkingId());
            mqKTDelOrderNoticeReq.setPlate(req.getPlateNum());
            sendMsgService.sendQueueMessageText(ObjectMapperUtils.getObjectMapper().writeValueAsString(mqKTDelOrderNoticeReq));
            Object result = redisService.getWithExpireTime(uuid, basicProperties.getAppNetworkTimeOut());
            if (result == null) {
                rsp.setMsg("取消车位预定信息通知车场失败！");
                logger.error("消息队列中获取消息失败, 取消车位预定信息通知车场失败！");
                return rsp;
            }
            MqKTDelOrderNoticeRsp mqKTDelOrderNoticeRsp = (MqKTDelOrderNoticeRsp) result;
            if (mqKTDelOrderNoticeRsp.getResult() == MqBusinessRsp.ERROR) {
                rsp.setMsg("取消车位预定信息通知车场失败！");
                logger.error("取消车位预定信息通知车场失败，车场返回错误信息：{}", mqKTDelOrderNoticeRsp.getStrError());
                return rsp;
            }
            rsp.setResult(1);
        } catch (Exception e) {
            logger.error("云端将酷停的取消车位预定的信息通知车场异常：{}", e);
            rsp.setMsg("服务器异常！");
        }
        return rsp;
    }

    @Override
    public ParkingList getParkingList() {
        ParkingList rsp = new ParkingList();
        rsp.setResult(0);
        try {
            ArrayList<ParkingItem> items = new ArrayList<>();
            List<Parking> parkings = parkingMapper.getByThirdId(ThirdConfig.KUTING);
            if (parkings != null) {
                for (Parking parking : parkings) {
                    ParkingItem item = new ParkingItem();
                    item.setId(parking.getId());
                    item.setName(parking.getName());
                    items.add(item);
                }
            }
            rsp.setParkingItems(items);
            rsp.setResult(1);
        } catch (Exception e) {
            logger.error("酷停获取车场列表异常:{}", e);
            rsp.setMsg("获取车场列表失败！");
        }
        return rsp;
    }

    @Override
    public GetFeeRsp getFee(GetFeeReq req) {
        GetFeeRsp rsp = new GetFeeRsp();
        try {
            rsp.setPlatenum(req.getPlateNum());
            rsp.setDeadline(req.getLefttime());
            Parking parking = parkingMapper.getParkingById(req.getParkingId());
            if (parking == null) {
                rsp.setResult(0);
                rsp.setMsg("车场id错误，获取费用失败！");
                return rsp;
            }
            String uuid = UUID.randomUUID().toString();
            MqGetFeeReq mqGetFeeReq = new MqGetFeeReq();
            mqGetFeeReq.setOptid(MqBusinessOpt.GETFEE);
            mqGetFeeReq.setUuid(uuid);
            mqGetFeeReq.setParkingId(parking.getId());
            mqGetFeeReq.setPlate(req.getPlateNum());
            mqGetFeeReq.setOutTime(req.getLefttime());
            sendMsgService.sendQueueMessageText(ObjectMapperUtils.getObjectMapper().writeValueAsString(mqGetFeeReq));
            Object result = redisService.getWithExpireTime(uuid, basicProperties.getAppNetworkTimeOut());
            if (result == null) {
                rsp.setResult(0);
                rsp.setMsg("获取费用失败！");
                logger.error("消息队列中获取消息失败, 酷停平台获取停车费用失败！");
                return rsp;
            }
            ObjectMapper objectMapper = ObjectMapperUtils.getObjectMapper();
            String resultStr = objectMapper.writeValueAsString(result);
            MqGetFeeRsp mqGetFeeRsp = objectMapper.readValue(resultStr, MqGetFeeRsp.class);
            if (mqGetFeeRsp.getResult() == MqBusinessRsp.ERROR) {
                rsp.setResult(0);
                rsp.setMsg("获取费用失败！");
                logger.error(mqGetFeeRsp.getStrError());
                return rsp;
            }
            rsp.setResult(1);
            rsp.setFee(mqGetFeeRsp.getFee());
        } catch (Exception e) {
            logger.error("酷停平台获取停车费用异常：{}", e);
            rsp.setResult(0);
            rsp.setMsg("服务器异常！");
        }
        return rsp;

    }

    @Override
    public UploadFeeRsp uploadFee(UploadFeeReq req) {
        UploadFeeRsp rsp = new UploadFeeRsp();
        rsp.setResult(0);
        try {
            rsp.setPlatenum(req.getPlateNum());
            Date outTime = null;
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            outTime = format.parse(req.getDeadline());
            // 校验parkingId
            List<Integer> parkingIds = thirdParkingMapMapper.getByThirdId(ThirdConfig.KUTING);
            if (parkingIds != null && !parkingIds.contains(req.getParkingId())) {
                rsp.setMsg("参数车场id错误！");
                return rsp;
            }
            Parking parking = parkingMapper.getParkingById(req.getParkingId());
            if (parking == null) {
                rsp.setResult(0);
                rsp.setMsg("参数车场id错误！");
                return rsp;
            }
            ThirdFee thirdFee = new ThirdFee();
            thirdFee.setThirdId(ThirdConfig.KUTING);
            thirdFee.setOrderId(req.getOrderid());
            thirdFee.setParkingId(req.getParkingId());
            thirdFee.setPlate(req.getPlateNum());
            thirdFee.setFee(req.getFee());
            thirdFee.setOutTime(outTime);
            thirdFee.setCreatedTime(new Date());
            thirdFeeMapper.insertThirdFee(thirdFee);

            logger.info("-------向车场发送酷停支付完成消息！--------");
            /*String uuid = UUID.randomUUID().toString();
            MqPayOrderReq mqPayFeeReq = new MqPayOrderReq();
            mqPayFeeReq.setOptid(MqBusinessOpt.PAYFEE);
            mqPayFeeReq.setUuid(uuid);
            mqPayFeeReq.setParkingId(parking.getId());
            mqPayFeeReq.setPlate(req.getPlateNum());
            mqPayFeeReq.setFee(req.getFee());
            mqPayFeeReq.setOutTime(DateUtil.convertDate2Seconds(outTime));
            mqPayFeeReq.setPayTime(DateUtil.convertDate2Seconds(new Date()));
            sendMsgService.sendQueueMessageText(ObjectMapperUtils.getObjectMapper().writeValueAsString(mqPayFeeReq));
            Object result = redisService.getWithExpireTime(uuid, basicProperties.getAppNetworkTimeOut());
            if (result == null) {
                rsp.setResult(0);
                rsp.setMsg("支付完成消息发送车场失败！");
                logger.info("消息队列中获取消息失败！");
                thirdFeeMapper.deleteById(thirdFee.getId());
                return rsp;
            }
            MqPayFeeRsp mqPayFeeRsp = (MqPayFeeRsp) result;
            if (mqPayFeeRsp.getResult() == MqBusinessRsp.SUCCESS) {
                rsp.setResult(1);
                rsp.setMsg("支付完成消息发送车场成功！");
                logger.info("{}支付完成消息发送车场{}成功！！",req.getPlateNum(), parking.getName());
            }else{
                // TODO: 2017/3/16 支付消息是持续发送，此处如何处理？？？
                thirdFeeMapper.deleteById(thirdFee.getId());
                rsp.setResult(0);
                rsp.setMsg("支付完成消息发送车场失败！");
                logger.info("{}支付完成消息发送车场{}成功，车场返回失败原因：{}",req.getPlateNum(), parking.getName(), mqPayFeeRsp.getStrError());
            }*/
        } catch (ParseException e) {
            logger.error("酷停平台上报停车费用，保存异常：日期格式化错误：{}", e);
            rsp.setMsg("日期格式错误！");
        } catch (Exception e) {
            logger.error("酷停平台上报停车费用，保存异常：{}", e);
            rsp.setMsg("上传失败！");
        }

        return rsp;
    }
}
